package jssia.database.verification;

import java.math.BigInteger;
import java.util.Set;

import jssia.database.mysql.columns.Column;
import jssia.database.mysql.columns.DecimalColumn;
import jssia.database.mysql.constants.Collation;

class ColumnSchema {

    private final String name;
    private final Class<? extends Column> type;
    private final BigInteger length;
    private final Collation collation;
    private final boolean nullable;
    private final boolean autoIncrement;
    private final String defaultValue;
    private final IndexSchema index;
    private final Set<String> values;
    private int precision;
    private int scale;

    public ColumnSchema(String name, Class<? extends Column> type, BigInteger length, String collation, boolean nullable, boolean autoIncrement, String defaultValue, IndexSchema index, Set<String> values) {
        this.type = type;
        this.name = name;
        this.length = length;
        try {
            this.collation = (collation == null) ? null : Collation.valueOf(collation.toUpperCase());
        } catch(IllegalArgumentException e) {
            throw new IllegalArgumentException("The collation " + collation
                    + " does not exist in " + Collation.class, e);
        }
        this.nullable = nullable;
        this.autoIncrement = autoIncrement;
        this.defaultValue = defaultValue;
        this.index = index;
        this.values = values;
    }

    public String getName() {
        return name;
    }

    public Class<? extends Column> getColumnType() {
        return type;
    }

    public BigInteger getLength() {
        return length;
    }

    public Collation getCollation() {
        return collation;
    }

    public boolean isNullable() {
        return nullable;
    }

    public boolean isAutoIncrement() {
        return autoIncrement;
    }

    public String getDefaultValue() {
        return defaultValue;
    }

    public IndexSchema getIndex() {
        return index;
    }

    public Set<String> getValueSet() {
        return values;
    }

    public void setPrecisionAndScale(int precision, int scale) {
        if (!type.equals(DecimalColumn.class))
            throw new IllegalStateException("Only Decimal types can have a scale and precision.  " +
                    "This column schema is of type " + type);
        this.precision = precision;
        this.scale = scale;
    }

    public int getPrecision() {
        if (!type.equals(DecimalColumn.class))
            throw new IllegalStateException("Only Decimal types can have a scale and precision.  " +
                    "This column schema is of type " + type);
        return precision;
    }

    public int getScale() {
        if (!type.equals(DecimalColumn.class))
            throw new IllegalStateException("Only Decimal types can have a scale and precision.  " +
                    "This column schema is of type " + type);
        return scale;
    }

    @Override
    public String toString() {
        StringBuilder builder = new StringBuilder();
        builder.append("ColumnSchema [name=").append(name).append(", type=")
                .append(type.getSimpleName()).append(", length=").append(length)
                .append(", collation=").append(collation).append(", nullable=")
                .append(nullable).append(", autoIncrement=")
                .append(autoIncrement).append(", defaultValue=")
                .append(defaultValue).append(", index=").append(index)
                .append(", values=").append(values).append("]\n");
        return builder.toString();
    }
}
